{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ideal-access",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defined \u001b[32mclass\u001b[39m \u001b[36mAnimal\u001b[39m\r\n",
       "defined \u001b[32mclass\u001b[39m \u001b[36mPet\u001b[39m\r\n",
       "defined \u001b[32mclass\u001b[39m \u001b[36mCat\u001b[39m\r\n",
       "defined \u001b[32mclass\u001b[39m \u001b[36mDog\u001b[39m\r\n",
       "defined \u001b[32mclass\u001b[39m \u001b[36mLion\u001b[39m\r\n",
       "defined \u001b[32mclass\u001b[39m \u001b[36mPetContainer\u001b[39m\r\n",
       "\u001b[36mdogContainer\u001b[39m: \u001b[32mPetContainer\u001b[39m[\u001b[32mDog\u001b[39m] = ammonite.$sess.cmd0$Helper$PetContainer@7a40c43d\r\n",
       "\u001b[36mcatContainer\u001b[39m: \u001b[32mPetContainer\u001b[39m[\u001b[32mCat\u001b[39m] = ammonite.$sess.cmd0$Helper$PetContainer@181ee2e"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abstract class Animal {\n",
    "    def name :String\n",
    "}\n",
    "\n",
    "abstract class Pet extends Animal {\n",
    "    \n",
    "}\n",
    "\n",
    "class Cat extends Pet {\n",
    "    override def name:String = \"Cat\"\n",
    "}\n",
    "\n",
    "class Dog extends Pet {\n",
    "    override def name:String =\"Dog\"\n",
    "}\n",
    "\n",
    "class Lion extends Animal {\n",
    "    override def name:String = \"Lion\"\n",
    "}\n",
    "\n",
    "class PetContainer[P<:Pet](p:P){\n",
    "    def pet:P = p\n",
    "}\n",
    "\n",
    "val dogContainer = new PetContainer[Dog](new Dog)\n",
    "val catContainer = new PetContainer[Cat](new Cat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "danish-fiber",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "cmd1.sc:125: type arguments [cmd1.this.cmd0.Lion] do not conform to class PetContainer's type parameter bounds [P <: Helper.this.Pet]\n",
      "val lionContainer = new PetContainer[Lion](new Lion)\n",
      "    ^cmd1.sc:1: type arguments [cmd1.this.cmd0.Lion] do not conform to class PetContainer's type parameter bounds [P <: Helper.this.Pet]\n",
      "val lionContainer = new PetContainer[Lion](new Lion)\n",
      "                        ^cmd1.sc:8: type arguments [cmd1.this.cmd0.Lion] do not conform to class PetContainer's type parameter bounds [P <: Helper.this.Pet]\n",
      "          .print(lionContainer, \"lionContainer\", _root_.scala.None)\n",
      "           ^cmd1.sc:8: type arguments [cmd1.this.cmd0.Lion] do not conform to class PetContainer's type parameter bounds [P <: Helper.this.Pet]\n",
      "          .print(lionContainer, \"lionContainer\", _root_.scala.None)\n",
      "                ^Compilation Failed"
     ]
    },
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "Compilation Failed"
     ]
    }
   ],
   "source": [
    "val lionContainer = new PetContainer[Lion](new Lion)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ordered-eligibility",
   "metadata": {},
   "outputs": [],
   "source": [
    "//类型下界\n",
    "\n",
    "trait Node[+B] {\n",
    "  def prepend(elem: B): Node[B]\n",
    "}\n",
    "\n",
    "case class ListNode[+B](h: B, t: Node[B]) extends Node[B] {\n",
    "  def prepend(elem: B): ListNode[B] = ListNode(elem, this)\n",
    "  def head: B = h\n",
    "  def tail: Node[B] = t\n",
    "}\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Scala",
   "language": "scala",
   "name": "scala"
  },
  "language_info": {
   "codemirror_mode": "text/x-scala",
   "file_extension": ".scala",
   "mimetype": "text/x-scala",
   "name": "scala",
   "nbconvert_exporter": "script",
   "version": "2.11.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
